using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Castle.DynamicProxy;
using Publicuse.Entity;
using Publicuse.Entity.AttributeUtil;
using Publicuse.Util;

namespace Publicuse.Autofac
{
  /// <summary>
  /// 操作日志拦截器
  /// </summary>
  public sealed class LogInterceptor : IInterceptor
  {
    private object[] input;

    public void Intercept(IInvocation invocation)
    {
      this.input = invocation.Arguments;
      invocation.Proceed();
      var loginUserCode = HttpContextExtendBase.GetLoginCode();
      var LoginrName = HttpContextExtendBase.GetLoginrName();
      var invokeResult = invocation.ReturnValue as CommonResult;
      invokeResult.etTime = DateTime.Now;
      var businessType = (BusinessType)input[0];
      var busTypeName = BusinessAttributeUtil.GetAttributeName<BusinessAttribute>(businessType);
      var businessActionType = (BusinessActionType)input[1];
      var busActionName = BusinessAttributeUtil.GetAttributeName<BusinessAttribute>(
        businessActionType
      );
      var methodName = input[3].ToString();
      BusinessActionType[] busatlist = new BusinessActionType[]
      {
        BusinessActionType.add,
        BusinessActionType.delete,
        BusinessActionType.update,
        BusinessActionType.import,
        BusinessActionType.reduction,
        BusinessActionType.run,
        BusinessActionType.stop,
        BusinessActionType.uploadfile
      };
      if (string.Compare(busActionName, "用户登陆", true) == 0)
      {
        var data = invokeResult.data as UserLoginResult;
        if (data != null)
        {
          loginUserCode = data.user.uCode;
          LoginrName = data.rName;
        }
        else
        {
          var userlogin = JsonUtil.ToObject<UserLogin>(input[2].ToString());
          loginUserCode = userlogin.name;
        }
      }
      if (busatlist.Any(o => o == businessActionType))
      {
        if (businessActionType == BusinessActionType.delete)
        {
          if (!methodName.Contains("100")) { }
        }
        else { }
      }
      if (businessActionType == BusinessActionType.delete)
      {
        if (methodName.Contains("100"))
          methodName = methodName.Replace("100", "永久");

        if (methodName.Contains("-9"))
          methodName = methodName.Replace("-9", "移除到回收站");
      }
      var parameter = input[2];
      var writeLogType = (BusinessLogType)input[4];
      if (invokeResult != null)
      {
        var headers = HttpContextExtendBase.Current.Request.Headers;
        if (headers.ContainsKey("X-Forwarded-For"))
        {
          HttpContextExtendBase.Current.Connection.RemoteIpAddress = IPAddress.Parse(
            headers["X-Forwarded-For"].ToString().Split(',', StringSplitOptions.RemoveEmptyEntries)[
              0
            ]
          );
        }
        if (headers.ContainsKey("X-Forwarded-For"))
        {
          HttpContextExtendBase.Current.Connection.RemoteIpAddress = IPAddress.Parse(
            headers["X-Forwarded-For"].ToString().Split(',', StringSplitOptions.RemoveEmptyEntries)[
              0
            ]
          );
        }
        var remoteIp =
          LogClass.GetIPAddress()
          + "|"
          + headers["X-Real-IP"].ToString()
          + "|"
          + headers["X-Forwarded-For"].ToString();
        if (string.Compare(remoteIp, "::1", true) == 0)
        {
          remoteIp = HttpContextExtendBase
            .Current.Connection.LocalIpAddress.MapToIPv4()
            ?.ToString();
        }
        if (remoteIp.Split(':').Length >= 3)
        {
          remoteIp = remoteIp.Split(':')[3];
        }
        if (!string.IsNullOrEmpty(remoteIp))
        {
          remoteIp = remoteIp.Replace("unknow", "").Replace("|", "");
        }
        var RemoteIpAddress = HttpContextExtendBase.Current.Connection.RemoteIpAddress;
        var ipaddress = string.Empty;
        var newripad = RemoteIpAddress.ToString();
        if (!string.IsNullOrEmpty(newripad))
        {
          if (string.Compare(newripad, "::1", true) != 0)
          {
            ipaddress = $"{remoteIp + "|" + RemoteIpAddress}";
          }
          else
          {
            ipaddress = remoteIp;
          }
        }
        else
        {
          ipaddress = remoteIp;
        }
        ipaddress = ipaddress.Replace("|::ffff:", "");
        var re = invokeResult.success ? "成功：" : "失败：";
        Log log = new Log()
        {
          lmodule = busTypeName,
          ltype = busActionName,
          luser = loginUserCode,
          lrole = LoginrName,
          lsuccess = invokeResult.success ? 1 : 2,
          status = 1,
          ipaddress = ipaddress
        };
        if (writeLogType != BusinessLogType.NoWrite)
        {
          if (parameter != null)
          {
            if (invokeResult.success)
              log.lcontent =
                loginUserCode + busActionName + re + invokeResult.data + parameter + methodName;
            else
              log.lcontent =
                loginUserCode + busActionName + re + invokeResult.msg + parameter + methodName;
          }
          else
          {
            if (invokeResult.success)
              log.lcontent = loginUserCode + busActionName + re + invokeResult.data + methodName;
            else
              log.lcontent = loginUserCode + busActionName + re + invokeResult.msg + methodName;
          }
          if (
            writeLogType == BusinessLogType.writeLogToDataBase
            || writeLogType == BusinessLogType.writeLogToFileAndDataBase
          )
          {
            AutofacLogUtil.GetInstance.WriteDataBase(log);
          }

          if (
            writeLogType == BusinessLogType.writeLogToFile
            || writeLogType == BusinessLogType.writeLogToFileAndDataBase
          )
            AutofacLogUtil.GetInstance.WriteLogOld(log.lmodule, log.lcontent, true);
        }
      }
    }
  }
}
